package my.mall.common.config

import com.auth0.jwt.exceptions.JWTVerificationException
import jakarta.servlet.http.HttpServletRequest
import jakarta.validation.ValidationException
import my.mall.common.annotation.Slf4j
import my.mall.common.annotation.Slf4j.Companion.log
import my.mall.common.enums.RespMetaEnum
import my.mall.common.exception.WebBaseException
import my.mall.common.pojo.CommonResp
import my.mall.common.util.RespUtils
import org.springframework.util.StringUtils
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.MissingServletRequestParameterException
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice

@Slf4j
@RestControllerAdvice
class GlobalExceptionHandler {

    @ExceptionHandler(MissingServletRequestParameterException::class)
    fun missingServletRequestParameterException(
        request: HttpServletRequest,
        e: MissingServletRequestParameterException
    ): CommonResp<*> {
        log.warn(" ====== Request url is [{}] ====== ", request.requestURL, e)
        return RespUtils.warning<Any>(RespMetaEnum.PARAM_ERROR)
    }

    @ExceptionHandler(MethodArgumentNotValidException::class)
    fun methodArgumentNotValidException(
        request: HttpServletRequest,
        e: MethodArgumentNotValidException
    ): CommonResp<*> {
        log.warn(" ====== Request url is [{}] ====== ", request.requestURL, e)
        var errMsg = "参数错误"
        val fieldError = e.bindingResult.fieldError
        if (fieldError != null && StringUtils.hasLength(fieldError.defaultMessage)) {
            errMsg = fieldError.field + fieldError.defaultMessage
        }
        return RespUtils.warning(400, errMsg)
    }

    @ExceptionHandler(ValidationException::class)
    fun validationException(request: HttpServletRequest, e: ValidationException): CommonResp<*> {
        log.warn(" ====== Request url is [{}] ====== ", request.requestURL, e)
        return RespUtils.warning<Any>(RespMetaEnum.PARAM_ERROR)
    }

    @ExceptionHandler(JWTVerificationException::class)
    fun tokenExpiredException(request: HttpServletRequest, e: JWTVerificationException): CommonResp<*> {
        log.warn(" ====== Request url is [{}] ====== ", request.requestURL, e)
        return RespUtils.warning<Any>(RespMetaEnum.NOT_LOGIN)
    }

    @ExceptionHandler(WebBaseException::class)
    fun webBaseException(request: HttpServletRequest, e: WebBaseException): CommonResp<*> {
        log.warn(" ====== Request url is [{}] ====== ", request.requestURL, e)
        return RespUtils.warning(e.status, e.msg)
    }

    @ExceptionHandler(Throwable::class)
    fun defaultErrorView(request: HttpServletRequest, e: Throwable): CommonResp<*> {
        log.warn(" ====== Request url is [{}] ====== ", request.requestURL, e)
        return RespUtils.warning<Any>(RespMetaEnum.TIMEOUT)
    }
}
